
template <class T>
class scoped_ptr {
 public:
   scoped_ptr();
   scoped_ptr(T* t);
   ~scoped_ptr();
   void Reset(T* t);
   T* get();
   T* operator->();
   T* release(); 
 private:
   T* t_;
};

template<class T>
scoped_ptr<T>::scoped_ptr() : t_(NULL) {
}


template<class T>
scoped_ptr<T>::scoped_ptr(T* t) : t_(t) {
}

template<class T>
scoped_ptr<T>::~scoped_ptr() {
  delete t_;
}
   
template<class T>
void scoped_ptr<T>::Reset(T* t) {
  delete t_;
  t_ = t;
}

template<class T>
T* scoped_ptr<T>::get() {
  return t_;
}

template<class T>
T* scoped_ptr<T>::operator->() {
  return t_;
}
 
template<class T>
T* scoped_ptr<T>::release() {
  T* tmp = t_;
  t_ = NULL;
  return tmp;
}

template <class T>
class scoped_array {
 public:
   scoped_array();
   scoped_array(T* t);
   ~scoped_array();
   void Reset(T* t);
   T* get();
   T* operator->();
   T& operator[](int index);
   T* release(); 

 private:
   T* t_;
};

template<class T>
scoped_array<T>::scoped_array() : t_(NULL) {
}


template<class T>
scoped_array<T>::scoped_array(T* t) : t_(t) {
}

template<class T>
scoped_array<T>::~scoped_array() {
  delete[] t_;
}
   
template<class T>
void scoped_array<T>::Reset(T* t) {
  delete[] t_;
  t_ = t;
}

template<class T>
T* scoped_array<T>::get() {
  return t_;
}

template<class T>
T* scoped_array<T>::operator->() {
  return t_;
}

template<class T>
T* scoped_array<T>::release() {
  T* tmp = t_;
  t_ = NULL;
  return tmp;
}


template<class T>
T& scoped_array<T>::operator[](int index) {
  return t_[index];
}
